package column

import (
	"fmt"
	"game/game-db/orm/metag"
	"reflect"
	"strings"
	"time"
	"unsafe"
)

// int64的数字列元数据
type Int64ColumnMeta struct {
	ColumnMeta
}

func (t *Int64ColumnMeta) FillValue(objField reflect.Value, fieldValue reflect.Value) {
	if objField.CanSet() {
		objField.SetInt(fieldValue.Interface().(int64))
	} else {
		objField = reflect.NewAt(objField.Type(), unsafe.Pointer(objField.UnsafeAddr())).Elem()
		objField.SetInt(fieldValue.Interface().(int64))
	}
}
func (t *Int64ColumnMeta) TakeValue(objField reflect.Value) interface{} {
	var i64Value int64
	if objField.CanInterface() {
		i64Value = objField.Interface().(int64)
	} else {
		objField = reflect.NewAt(objField.Type(), unsafe.Pointer(objField.UnsafeAddr())).Elem()
		i64Value = objField.Interface().(int64)
	}
	return i64Value
}

func (t *Int64ColumnMeta) DbColumnType() string {
	return "bigint"
}

func (t *Int64ColumnMeta) DefaultValue() string {
	if t.defaultValue == "" {
		return "DEFAULT 0"
	} else {
		return fmt.Sprintf("DEFAULT %s", t.defaultValue)
	}
}

func (t *Int64ColumnMeta) IsChange(dbColumnType string, dbColumnExtra string) bool {
	return !strings.HasPrefix(dbColumnType, "bigint")
}

// 用int64表示的时间列
type Int64TimeColumnMeta struct {
	ColumnMeta
}

func (t *Int64TimeColumnMeta) FillValue(objField reflect.Value, fieldValue reflect.Value) {
	timeStr := fieldValue.Interface().(string)
	value, err := time.ParseInLocation("2006-01-02 15:04:05", timeStr, time.Local)
	if err != nil {
		setValue(objField, reflect.ValueOf(time.Now().UnixMilli()))
	} else {
		setValue(objField, reflect.ValueOf(value.UnixMilli()))
	}
}
func (t *Int64TimeColumnMeta) TakeValue(objField reflect.Value) interface{} {
	var i64Value int64
	if objField.CanInterface() {
		i64Value = objField.Interface().(int64)
	} else {
		objField = reflect.NewAt(objField.Type(), unsafe.Pointer(objField.UnsafeAddr())).Elem()
		i64Value = objField.Interface().(int64)
	}
	return time.UnixMilli(i64Value)
}

func (t *Int64TimeColumnMeta) DbColumnType() string {
	return "datetime"
}

func (t *Int64TimeColumnMeta) DefaultValue() string {
	if t.defaultValue == "" {
		return "DEFAULT NULL"
	} else {
		return fmt.Sprintf("DEFAULT '%s'", t.defaultValue)
	}
}

func (t *Int64TimeColumnMeta) IsChange(dbColumnType string, dbColumnExtra string) bool {
	return !strings.HasPrefix(dbColumnType, "datetime")
}

func NewInt64Field(structField reflect.StructField, columnMetag metag.ColumnMetag) IColumnMeta {
	if columnMetag.Extra == "time" {
		var meta Int64TimeColumnMeta
		meta.fillBaseValue(structField, columnMetag)
		return &meta
	} else {
		var meta Int64ColumnMeta
		meta.fillBaseValue(structField, columnMetag)
		return &meta
	}
}
